package cn.qn.service.impl.security;

import cn.qn.dto.security.MenuDTO;
import cn.qn.enums.BooleanEnum;
import cn.qn.mapper.member.MemberMapper;
import cn.qn.moudle.security.Menu;
import cn.qn.moudle.security.Role;
import cn.qn.repository.security.MenuRepository;
import cn.qn.repository.security.RoleRepository;
import cn.qn.service.security.MenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Auther: Bryant
 * @Date: 2018/5/25
 * @Description:
 */
@com.alibaba.dubbo.config.annotation.Service(interfaceClass = MenuService.class)
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuRepository menuRepository;
    @Autowired
    private RoleRepository rolesRepository;
    @Resource
    private MemberMapper memberMapper;

    @Override
    public List<MenuDTO> getAllMenu() {
        List<MenuDTO> list = new ArrayList<MenuDTO>();
        List<Menu> menus = menuRepository.findAll();
        for (Menu menu : menus) {
            MenuDTO dto = new MenuDTO();
            dto.setId(menu.getId());
            dto.setName(menu.getName());
            dto.setUrl(menu.getUrl());
            List<Role> roles = rolesRepository.findByMenuId(menu.getId());
            dto.setRoles(roles);
            list.add(dto);
        }
        return list;
    }

    @Override
    public Set<MenuDTO> getAllParentMenu() {
        List<Menu> parents = menuRepository.findByParentIdOrderByPriority(0);
        Set<MenuDTO> menus = new TreeSet<>();
        if (null != parents && !parents.isEmpty()) {
            parents.stream().forEach(p -> {
                MenuDTO dto = new MenuDTO();
                BeanUtils.copyProperties(p, dto);
                List<Menu> child = menuRepository.findByParentIdOrderByPriority(p.getId());
                dto.setChildren(child);
                menus.add(dto);
            });
        }
        return menus;
    }

    @Override
    public Set<MenuDTO> findMenusByMemberId(String userId) {
        List<Role> roles = rolesRepository.findByUserId(userId);
        List<MenuDTO> menusAll = new ArrayList<>();
        for (Role r : roles) {
            if (r.getStatus().equals(BooleanEnum.TRUE.getCode())) {
                Map<String, Object> map = new HashMap<>();
                map.put("status", 1);
                map.put("roleId", r.getId());
                menusAll = memberMapper.findMenuByRoleIdAndParentId(map);
            }
        }
        Map<Integer, MenuDTO> map = new HashMap<>();
        menusAll.stream().forEach(t -> {
            Integer parentId = t.getParentId();
            if (!parentId.equals(0)) {
                MenuDTO menu = new MenuDTO();
                if (map.containsKey(parentId)) {
                    menu = map.get(parentId);
                } else {
                    Menu m = menuRepository.findById(parentId).get();
                    BeanUtils.copyProperties(m, menu);
                }
                List<Menu> list = menu.getChildren();
                if (null == list) {
                    list = new ArrayList<>();
                }
                Menu m = new Menu();
                BeanUtils.copyProperties(t, m);
                list.add(m);
                menu.setChildren(list);
                map.put(parentId, menu);
            } else {
                if (t.getPriority().equals(0)) {
                    map.put(0, t);
                }
            }
        });
        Set<MenuDTO> set = new TreeSet<>();
        set.addAll(map.values());
        return set;
    }

    @Override
    public Set<MenuDTO> menuPage() {
        List<Menu> parents = menuRepository.findByParentIdOrderByPriority(0);
        Set<MenuDTO> menus = new TreeSet<>();
        if(null!=parents && !parents.isEmpty()){
            parents.stream().forEach(p->{
                MenuDTO dto = new MenuDTO();
                BeanUtils.copyProperties(p,dto);
                List<Menu> child = menuRepository.findByParentIdOrderByPriority(p.getId());
                dto.setChildren(child);
                menus.add(dto);
            });
        }
        return menus;
    }
}
